#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>

int ticket = 1000;

//加锁方案二    全局锁
pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;

class ThreadData
{
public:
    ThreadData(const std::string &n,pthread_mutex_t &lock)
        :name(n),
        lockp(&lock)
    {

    }

    ~ThreadData(){}
    std::string name;
    pthread_mutex_t *lockp;
};

void *route(void *arg)
{
    ThreadData *td = static_cast<ThreadData*>(arg);
    while(1)
    {   
        //加锁方案一   局部锁
        // pthread_mutex_lock(td->lockp);

        //全局锁
        pthread_mutex_lock(&glock);
////////////////////////    临界区    /////////////////////
        if(ticket > 0)
        {
            usleep(1000);
            printf("%s sells ticket: %d\n", td->name.c_str() ,ticket);
                ticket--;
        // pthread_mutex_unlock(td->lockp);      //在这解锁   虽然是锁，但是也是函数，要符合规范！   局部锁

            pthread_mutex_unlock(&glock);
        }
/////////////////////////   临界区   ///////////////////////

        else
        {
        //解锁写了两次但是只会执行一次！
            // pthread_mutex_unlock(td->lockp);    //防止票数为0，就会进入else，锁没有释放，就在这也加上一个unlock
            
            pthread_mutex_unlock(&glock);    //全局锁的解锁
            break;
        }
    }
    return nullptr;
}

int main(void)
{
    pthread_mutex_t lock;
    
    //初始化 锁
    pthread_mutex_init(&lock,nullptr);   //初始化 锁

    pthread_t t1,t2,t3,t4;

    ThreadData *td1 = new ThreadData("thread 1",lock);
    pthread_create(&t1,NULL,route,td1);

    ThreadData *td2 = new ThreadData("thread 2",lock);
    pthread_create(&t2,NULL,route,td2);

    ThreadData *td3 = new ThreadData("thread 3",lock);
    pthread_create(&t3,NULL,route,td3);

    ThreadData *td4 = new ThreadData("thread 4",lock);
    pthread_create(&t4,NULL,route,td4);

    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
    pthread_join(t3,NULL);
    pthread_join(t4,NULL);

    //结束  把锁销毁
    pthread_mutex_destroy(&lock);

    return 0;
}

